from fastapi import APIRouter, File, UploadFile, HTTPException, Request
from fastapi.responses import JSONResponse, FileResponse
import os
import shutil
import zipfile
import tempfile
from datetime import datetime
from pathlib import Path
import uuid
from epub_split import main as epub_split_main
from epub_split import remove_empty_lines_from_epub

router_module = APIRouter()

# 创建存储上传文件和处理结果的目录
UPLOAD_DIR = Path("upload_files")
RESULTS_DIR = Path("static/results")
STATIC_URL = "/static/results"

# 确保目录存在
UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
RESULTS_DIR.mkdir(parents=True, exist_ok=True)

@router_module.get("/")
def index():
    return {"message": "EPUB文件拆分服务"}

@router_module.post("/balanced")
async def balanced_split(request: Request, file: UploadFile = File(...), max_size_mb: int = 30):
    """
    上传EPUB文件并使用均衡拆分方式拆分
    
    - **file**: EPUB文件
    - **max_size_mb**: 拆分后每个文件的最大大小，单位MB，默认30MB
    """
    # 检查文件类型
    if not file.filename.lower().endswith('.epub'):
        raise HTTPException(status_code=400, detail="只支持EPUB格式文件")
    
    # 获取原始文件名（不带扩展名）
    original_filename = os.path.splitext(os.path.basename(file.filename))[0]
    
    # 创建唯一的处理ID
    process_id = str(uuid.uuid4())
    
    # 创建临时工作目录
    temp_dir = Path(tempfile.mkdtemp())
    upload_path = temp_dir / file.filename  # 使用原始文件名
    output_dir = temp_dir / "output"
    output_dir.mkdir(exist_ok=True)
    
    try:
        # 保存上传的文件
        with open(upload_path, "wb") as buffer:
            shutil.copyfileobj(file.file, buffer)
        
        # 调用EPUB拆分函数
        result = epub_split_main(
            input_file=str(upload_path),
            output_directory=str(output_dir),
            max_size_mb=max_size_mb,
            split_mode="balanced"
        )
        
        if not result:
            raise HTTPException(status_code=500, detail="EPUB拆分失败")
        
        # 检查是否有生成的文件
        output_files = list(output_dir.glob("*.epub"))
        if not output_files:
            raise HTTPException(status_code=500, detail="未生成任何拆分文件")
        
        # 创建结果目录
        result_dir = RESULTS_DIR / process_id
        result_dir.mkdir(exist_ok=True)
        
        # 创建ZIP压缩包 - 使用原始文件名作为压缩包名称的一部分
        zip_filename = f"{original_filename}_split_{process_id}.zip"
        zip_path = result_dir / zip_filename
        
        with zipfile.ZipFile(zip_path, 'w') as zipf:
            for epub_file in output_files:
                # 保持原始文件名，直接将文件添加到ZIP中
                zipf.write(epub_file, epub_file.name)
        
        # 获取主机基础URL
        base_url = str(request.base_url).rstrip('/')  # 例如 http://example.com:8000
        
        # 配置直接下载的完整URL
        download_endpoint = f"{base_url}/epub_split/download/{process_id}/{zip_filename}"
        
        # 将结果文件移动到永久存储
        for epub_file in output_files:
            shutil.copy2(epub_file, result_dir)
        
        return {
            "status": "success",
            "message": f"EPUB文件已成功拆分为{len(output_files)}个文件",
            "file_count": len(output_files),
            "download_url": download_endpoint,
            "files": [epub_file.name for epub_file in output_files]
        }
    
    except Exception as e:
        # 记录详细错误信息
        import traceback
        error_details = traceback.format_exc()
        print(f"拆分EPUB时出错: {error_details}")
        
        raise HTTPException(status_code=500, detail=f"处理文件时发生错误: {str(e)}")
    
    finally:
        # 清理临时文件
        if temp_dir.exists():
            shutil.rmtree(temp_dir)

@router_module.post("/remove_empty_lines")
async def remove_empty_lines(request: Request, file: UploadFile = File(...)):
    """
    上传EPUB文件并去除其中HTML文件的空行
    
    - **file**: EPUB文件
    """
    # 检查文件类型
    if not file.filename.lower().endswith('.epub'):
        raise HTTPException(status_code=400, detail="只支持EPUB格式文件")
    
    # 获取原始文件名（不带扩展名）
    original_filename = os.path.splitext(os.path.basename(file.filename))[0]
    
    # 创建唯一的处理ID
    process_id = str(uuid.uuid4())
    
    # 创建临时工作目录
    temp_dir = Path(tempfile.mkdtemp())
    upload_path = temp_dir / file.filename  # 使用原始文件名
    output_dir = temp_dir / "output"
    output_dir.mkdir(exist_ok=True)
    
    try:
        # 保存上传的文件
        with open(upload_path, "wb") as buffer:
            shutil.copyfileobj(file.file, buffer)
        
        # 设置输出文件路径
        output_filename = f"{original_filename}_no_empty_lines.epub"
        output_path = output_dir / output_filename
        
        # 检查并安装依赖
        from epub_split import check_and_install_dependencies
        check_and_install_dependencies()
        
        # 调用空行去除函数
        result = remove_empty_lines_from_epub(str(upload_path), str(output_path))
        
        if not result:
            raise HTTPException(status_code=500, detail="EPUB空行去除失败")
        
        # 检查是否生成了输出文件
        if not output_path.exists():
            raise HTTPException(status_code=500, detail="未生成处理后的文件")
        
        # 创建结果目录
        result_dir = RESULTS_DIR / process_id
        result_dir.mkdir(exist_ok=True)
        
        # 复制处理后的文件到结果目录
        result_file_path = result_dir / output_filename
        shutil.copy2(output_path, result_file_path)
        
        # 获取主机基础URL
        base_url = str(request.base_url).rstrip('/')  # 例如 http://example.com:8000
        
        # 配置直接下载的完整URL
        download_endpoint = f"{base_url}/epub_split/download/{process_id}/{output_filename}"
        
        return {
            "status": "success",
            "message": "EPUB文件空行去除成功",
            "download_url": download_endpoint,
            "filename": output_filename
        }
    
    except Exception as e:
        # 记录详细错误信息
        import traceback
        error_details = traceback.format_exc()
        print(f"处理EPUB文件时出错: {error_details}")
        
        raise HTTPException(status_code=500, detail=f"处理文件时发生错误: {str(e)}")
    
    finally:
        # 清理临时文件
        if temp_dir.exists():
            shutil.rmtree(temp_dir)

@router_module.get("/download/{process_id}/{filename}")
async def download_file(process_id: str, filename: str):
    """
    提供文件直接下载的端点
    """
    file_path = RESULTS_DIR / process_id / filename
    
    if not file_path.exists():
        raise HTTPException(status_code=404, detail="文件不存在或已过期")
    
    return FileResponse(
        path=str(file_path), 
        filename=filename,
        media_type="application/zip"
    )
